package main.leetcode.clockin.September;

import main.datastruc.TreeNode;

import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;

/**
 * 145. 二叉树的后序遍历
 *
 * <p>给定一个二叉树，返回它的 后序 遍历。
 *
 * <p>示例: <br>
 * 输入: [1,null,2,3] <br>
 * 输出: [3,2,1]
 *
 * <p>进阶: 递归算法很简单，你可以通过迭代算法完成吗？
 */
public class day29 {

    /** 迭代 */
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if (root == null) {
            return res;
        }
        Deque<TreeNode> stack = new LinkedList<>();
        TreeNode node = root;
        // 标记已被访问过的右结点，例如 [1,null,2,3] 的特例
        TreeNode pre = null;
        while (node != null || !stack.isEmpty()) {
            // 左路全部压入栈
            while (node != null) {
                stack.push(node);
                node = node.left;
            }
            node = stack.poll();
            // 如果没有右节点或者右节点已被访问过
            //  对于后者，例如 [1,null,2,3] 的特例情况下，while循环会永远进行
            if (node.right == null || node.right == pre) {
                res.add(node.val);
                pre = node;
                node = null;
            } else {
                // 如果有右节点，当前节点重新压入栈
                stack.push(node);
                node = node.right;
            }
        }
        return res;
    }

    //    /** 递归 */
    //    private List<Integer> res = new LinkedList<>();
    //    public List<Integer> postorderTraversal(TreeNode root) {
    //        if(root == null) {
    //            return res;
    //        }
    //        postorderTraversal(root.left);
    //        postorderTraversal(root.right);
    //        res.add(root.val);
    //        return res;
    //    }

}
